﻿using Caliburn.Micro;
using CefSharp;
using CefSharp.Wpf;
using GetMan.Core.Browser;
using GetMan.Core.Commands;
using GetMan.Core.Common;
using GetMan.Core.DB.Entities;
using GetMan.Core.DB.Services.Collection;
using GetMan.Core.DB.Services.Request;
using GetMan.Core.DB.Services.WorkSpace;
using GetMan.Core.Extensions;
using GetMan.Core.infrastructure.BaseC;
using GetMan.Core.infrastructure.IViewModels;
using GetMan.Core.Models;
using GetMan.Models;
using MapsterMapper;
using Rubyer;
using Rubyer.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace GetMan.ViewModels
{
    /// <summary>
    /// 主窗体
    /// </summary>
    [Export(typeof(IMainViewModel))]
    [Export(nameof(MainViewModel), typeof(MainViewModel))]
    public class MainViewModel : ViewModelBase<MainViewModel>, IMainViewModel
    {
        [Import]
        private IWorkSpaceService workSpaceSerivce;
        [Import]
        private INodeService nodeService;
        [Import]
        private IRequestService requestService;
        [Import]
        private IMapper _mapper;

        #region 命令
        /// <summary>
        /// 树节点选中命令
        /// </summary>
        public ICommand TreeViewItemSelectedCommand
        {
            get; private set;
        }

        #endregion

        public MainViewModel() : base()
        {
            TreeViewItemSelectedCommand = new RelayCommand(NodeTree_SelectedItemChanged);
        }

        ~MainViewModel()
        {
        }

        protected override Task OnDeactivateAsync(bool close, CancellationToken cancellationToken)
        {
            base.OnDeactivateAsync(close, cancellationToken);
            if (close)
            {
                #region 释放Browser
                try
                {
                    if (browser != null)
                    {
                        browser.Dispose();
                        Cef.Shutdown();
                    }
                }
                catch (Exception ex)
                {
                    AddLog($"释放Browser异常:{ex.Message}");
                    AddLog(ex.StackTrace);
                }
                #endregion
            }
            return Task.CompletedTask;
        }

        #region 属性
        private ChromiumWebBrowser browser;

        /// <summary>
        /// 树状节点集合
        /// </summary>
        private BindableCollection<NodeTreeModel> nodeTreeModels;
        public BindableCollection<NodeTreeModel> NodeTreeModels
        {
            get => nodeTreeModels;
            set
            {
                nodeTreeModels = value;
                NotifyOfPropertyChange(() => NodeTreeModels);
            }
        }

        private RequestDataMode dataMode = RequestDataMode.none;
        public RequestDataMode DataMode
        {
            get => dataMode;
            set
            {
                dataMode = value;
                NotifyOfPropertyChange(() => DataMode);
            }
        }


        /// <summary>
        /// 窗口标题
        /// </summary>
        private BindableCollection<DataModeModel> _dataBodyModes;
        public BindableCollection<DataModeModel> DataBodyModes
        {
            get => _dataBodyModes;
            set
            {
                _dataBodyModes = value;
                NotifyOfPropertyChange(() => DataBodyModes);
            }
        }
        private DataModeModel selectedDataBodyMode;
        public DataModeModel SelectedDataBodyMode
        {
            get => selectedDataBodyMode;
            set
            {
                selectedDataBodyMode = value;
                NotifyOfPropertyChange(() => SelectedDataBodyMode);
            }
        }

        /// <summary>
        /// 窗口标题
        /// </summary>
        private string _title;
        public string Title
        {
            get => _title;
            set
            {
                _title = value;
                NotifyOfPropertyChange(() => Title);
            }
        }

        private RequestBodyModel _body;
        public RequestBodyModel Body
        {
            get => _body;
            set
            {
                _body = value;
                NotifyOfPropertyChange(() => Body);
            }
        }

        private string crumbs;
        public string Crumbs
        {
            get => crumbs;
            set
            {
                crumbs = value;
                NotifyOfPropertyChange(() => Crumbs);
            }
        }
        private NodeTreeModel selectedNode;
        public NodeTreeModel SelectedNode
        {
            get => selectedNode;
            set
            {
                selectedNode = value;
                NotifyOfPropertyChange(() => SelectedNode);
            }
        }

        /// <summary>
        /// 请去报文
        /// </summary>
        private BindableCollection<LabelModel> reqContents;
        public BindableCollection<LabelModel> ReqContents
        {
            get => reqContents;
            set
            {
                reqContents = value;
                NotifyOfPropertyChange(() => ReqContents);
            }
        }

        #region 请求方式
        /// <summary>
        /// 选项列表
        /// </summary>
        private List<string> _methods;
        public List<string> Methods
        {
            get => _methods;
            set
            {
                _methods = value;
                NotifyOfPropertyChange(() => Methods);
            }
        }

        /// <summary>
        /// 默认选择请求方式
        /// </summary>
        private string _selectedMethod;
        public string SelectedMethod
        {
            get => _selectedMethod;
            set
            {
                _selectedMethod = value;
                NotifyOfPropertyChange(() => SelectedMethod);
            }
        }
        #endregion

        /// <summary>
        /// 是否请求发送中
        /// </summary>
        private BindableCollection<ParamsModel> _paramsList;
        public BindableCollection<ParamsModel> ParamsList
        {
            get => _paramsList;
            set
            {
                _paramsList = value;
                NotifyOfPropertyChange(() => ParamsList);
            }
        }

        /// <summary>
        /// 请求URL
        /// </summary>
        private string _url;
        public string Url
        {
            get => _url;
            set
            {
                if (_url == value)
                    return;
                _url = value;
                NotifyOfPropertyChange(() => Url);
            }
        }

        /// <summary>
        /// 是否请求发送中
        /// </summary>
        private bool _isSend;
        public bool IsSend
        {
            get => _isSend;
            set
            {
                _isSend = value;
                NotifyOfPropertyChange(() => IsSend);
            }
        }

        private string responseContent;
        public string ResponseContent
        {
            get => responseContent;
            set
            {
                responseContent = value;
                NotifyOfPropertyChange(() => ResponseContent);
            }
        }

        /// <summary>
        /// Url参数视图
        /// </summary>
        private ParamsListViewModel paramsListViewModel;
        public ParamsListViewModel ParamsListViewModel
        {
            get
            {
                return paramsListViewModel;
            }
            set
            {
                Set(ref paramsListViewModel, value);
            }
        }

        /// <summary>
        /// Header参数视图
        /// </summary>
        private KeyValueListViewModel headerListViewModel;
        public KeyValueListViewModel HeaderListViewModel
        {
            get
            {
                return headerListViewModel;
            }
            set
            {
                Set(ref headerListViewModel, value);
            }
        }

        /// <summary>
        /// FormData参数视图
        /// </summary>
        private KeyValueListViewModel formDataViewModel;
        public KeyValueListViewModel FormDataViewModel
        {
            get
            {
                return formDataViewModel;
            }
            set
            {
                Set(ref formDataViewModel, value);
            }
        }

        /// <summary>
        /// x-www-form-urlencode参数视图
        /// </summary>
        private KeyValueListViewModel formUrlEncodeDataViewModel;
        public KeyValueListViewModel FormUrlEncodeDataViewModel
        {
            get
            {
                return formUrlEncodeDataViewModel;
            }
            set
            {
                Set(ref formUrlEncodeDataViewModel, value);
            }
        }

        /// <summary>
        /// 工作列表
        /// </summary>
        private BindableCollection<WorkSpaceEntity> workspaces;
        public BindableCollection<WorkSpaceEntity> Workspaces
        {
            get => workspaces;
            set
            {
                workspaces = value;
                NotifyOfPropertyChange(() => Workspaces);
            }
        }

        /// <summary>
        /// 选中工作领域
        /// </summary>
        public WorkSpaceEntity selectedWorkspace;
        public WorkSpaceEntity SelectedWorkspace
        {
            get => selectedWorkspace;
            set
            {
                selectedWorkspace = value;
                NotifyOfPropertyChange(() => SelectedWorkspace);
            }
        }

        #endregion

        public void Refresh()
        {
            OnViewLoaded(GetView());
        }

        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
            NodeTreeModels = new BindableCollection<NodeTreeModel>();
            ReqContents = new BindableCollection<LabelModel>();
            Methods = new List<string>
            {
                "GET",
                "POST",
                "PUT",
                "DELETE",
                "HEAD",
                "OPTIONS"
            };
            SelectedMethod = Methods.FirstOrDefault();

            #region Param参数视图初始化
            ParamsListViewModel = new ParamsListViewModel(Url);
            ParamsListViewModel.PropertyChanged += (sender, args) =>
            {
                Url = ParamsListViewModel.Url;
            };
            #endregion

            #region Header参数视图初始化
            HeaderListViewModel = new KeyValueListViewModel();
            #endregion

            #region Body参数视图初始化
            FormDataViewModel = new KeyValueListViewModel();
            FormUrlEncodeDataViewModel = new KeyValueListViewModel();
            #endregion

            DataBodyModes = CreateDataModel.CreateList(typeof(BodyTypeEnum));
            SelectedDataBodyMode = DataBodyModes.FirstOrDefault();
            //初始化Browser
            InitWebBrowser();

            #region 数据集填充
            GetWorkSpaces();
            #endregion


        }


        #region Browser事件管理
        /// <summary>
        /// 初始化Browser
        /// </summary>
        /// <param name="proxyIp"></param>
        public void InitWebBrowser(string proxyIp = "")
        {
            try
            {
                string cachePath = "cache";
                string cacheFullPath = System.IO.Path.GetFullPath(cachePath);
                if (!Directory.Exists(cachePath))
                {
                    Directory.CreateDirectory(cachePath);
                }
                var cefSettings = new CefSettings { CachePath = cacheFullPath, };

                if (!string.IsNullOrEmpty(proxyIp))
                    cefSettings.CefCommandLineArgs.Add("proxy-server", proxyIp);
                Cef.Initialize(cefSettings);
                browser = new ChromiumWebBrowser();

                //允许以同步的方式注册C#的对象到JS中
                browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
                CefSharpSettings.WcfEnabled = true;

                //注册C#的对象到JS中的代码必须在Cef的Browser加载之前调用
                browser.JavascriptObjectRepository.Register("cefSharpReffer", new CefSharpReffer(), false, BindingOptions.DefaultBinder);
                CefSharpSettings.WcfEnabled = true;

                string htmlUrl = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/CodeMirrorEdit.html");
                browser.LoadUrl(htmlUrl);


                //查找Grid
                if (GetView() is Control view)
                {
                    var grid = view.FindName("root_browser") as Grid;
                    if (grid != null)
                    {
                        grid.Children.Clear();
                        grid.Children.Add(browser);
                    }
                }

            }
            catch (Exception ex)
            {
                AddLog($"初始化ChromiumWebBrowser异常：{ex.Message}", nameof(InitWebBrowser));
                AddLog(ex.StackTrace, nameof(InitWebBrowser));
            }
        }

        /// <summary>
        /// 格式化JSON代码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void CallBrowser_FuncBeatify()
        {
            var jsFunc = "formatJson()";
            if (SelectedDataBodyMode.Name.Equals(BodyTypeEnum.xml.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                jsFunc = "formatXml()";
            }
            if (browser.CanExecuteJavascriptInMainFrame)
                browser.ExecuteScriptAsync(jsFunc);
        }
        /// <summary>
        /// 获取编辑器内容
        /// </summary>
        /// <returns></returns>
        private async Task<string> GetCodeStringAsync()
        {
            try
            {
                if (!browser.CanExecuteJavascriptInMainFrame)
                {
                    return string.Empty;
                }
                var result = await browser.EvaluateScriptAsync(@"getValue();");
                if (result.Success && result.Result != null)
                {
                    string codeString = result.Result.ToString();
                    if (codeString.NotNull())
                    {
                        codeString = codeString.Replace("\r", "");
                        codeString = codeString.Replace("\n", "");
                        codeString = codeString.Replace("\t", "");
                    }
                    return codeString;
                }
                return string.Empty;
            }
            catch (Exception ex)
            {
                AddLog("获取Browser编辑器内容异常", nameof(GetCodeStringAsync));
                AddLog(ex.Message, nameof(GetCodeStringAsync));
                AddLog(ex.StackTrace, nameof(GetCodeStringAsync));
                throw new Exception("获取Body内容异常");
            }
        }
        /// <summary>
        /// 获取编辑器内容
        /// </summary>
        /// <returns></returns>
        private async Task<bool> SetCodeStringAsync(string jsonString)
        {
            if (jsonString.IsNull())
            {
                jsonString = "";
            }
            //var str = "{\"name\":\"123\"}";
            if (!browser.CanExecuteJavascriptInMainFrame)
                return false;
            var result = await browser.GetMainFrame().EvaluateScriptAsync($"setValue('{jsonString}');");
            if (result.Success)
            {
                return true;
            }
            MessageBox.Show(result.Message);
            AddLog(result.Message, nameof(SetCodeStringAsync));
            return false;
        }

        /// <summary>
        /// 变更选项事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public async void ParamsTab_ChangedAsync(object sender, SelectionChangedEventArgs e)
        {
            var tab = (TabControl)sender;
            if (tab == null)
                return;
            var tabItem = (TabItem)tab.SelectedItem;
            if (tabItem.Tag?.ToString() == "raw")
            {
                browser.LoadingStateChanged += OnLoadingStateChanged;
            }
            SelectedTag = tabItem.Tag?.ToString();

            switch (tabItem.Tag?.ToString())
            {
                case "raw":
                    DataMode = RequestDataMode.raw;
                    break;
                case "form-data":
                    DataMode = RequestDataMode.formData;
                    break;
                case "x-www-form-urlencoded":
                    DataMode = RequestDataMode.formUrlEncode;
                    break;
                case "none":
                default:
                    DataMode = RequestDataMode.none;
                    break;
            }

        }

        private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs e)
        {
            if (!e.IsLoading)
            {
                // 页面加载完成后执行脚本
                SetCodeStringAsync(Body?.Content).GetAwaiter();
                CallBrowser_FuncBeatify();
                browser.LoadingStateChanged -= OnLoadingStateChanged;
            }
        }
        /// <summary>
        /// 当前选中参数模式
        /// </summary>
        public string SelectedTag
        {
            get; set;
        }
        #endregion


        #region 事件方法
        /// <summary>
        /// 请求线程管理
        /// </summary>
        private CancellationTokenSource sendCts;

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async void SendAsync()
        {
            if (IsSend)
            {
                throw new Exception("正在请求中");
            }
            IsSend = true;
            string rawJson = string.Empty;

            //请求参数获取

            rawJson = await GetCodeStringAsync();

            sendCts = new CancellationTokenSource();

            HttpResponseMessage rep = null;
            HttpRequestMessage req = new HttpRequestMessage();
            req.RequestUri = new Uri(Url);
            req.Method = new HttpMethod(SelectedMethod);

            AddLog($"请求地址:{Url}");

            //请求头配置
            req.Headers.Clear();
            var checkedHeaders = HeaderListViewModel.ParamsList
                .Where(x => x.ShowCheckBox && x.IsChecked);
            var contentType = checkedHeaders.LastOrDefault(x => x.Key.Equals("content-type", StringComparison.OrdinalIgnoreCase));
            foreach (var header in checkedHeaders)
            {
                if (header.Key.Equals("content-type", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                req.Headers.Add(header.Key, header.Value);
            }

            if (!SelectedMethod.EqualsIgnoreCase("get"))
            {
                StringBuilder reqData = new StringBuilder();
                List<string> str = new List<string>();
                switch (DataMode)
                {
                    case RequestDataMode.formData:
                        var formDatas = FormDataViewModel.ParamsList.Where(x => x.ShowCheckBox && x.IsChecked);
                        var form = new MultipartFormDataContent();
                        foreach (var item in formDatas)
                        {
                            form.Add(new StringContent(item.Key), item.Value);
                        }
                        if (contentType != null)
                        {
                            form.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType.Value);
                        }
                        AddLog($"FormData请求参数：{await form.ReadAsStringAsync()}");
                        req.Content = form;
                        break;
                    case RequestDataMode.formUrlEncode:
                        var formUrlDatas = FormUrlEncodeDataViewModel.ParamsList
                            .Where(x => x.ShowCheckBox && x.IsChecked);
                        Dictionary<string, string> formUrlDataDic = new Dictionary<string, string>();
                        foreach (var item in formUrlDatas)
                        {
                            formUrlDataDic[item.Key] = item.Value;
                        }
                        var formUrlEncode = new FormUrlEncodedContent(formUrlDataDic);
                        if (contentType != null)
                        {
                            formUrlEncode.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType.Value);
                        }
                        req.Content = formUrlEncode;
                        AddLog($"FormUrlEncode请求参数：{await formUrlEncode.ReadAsStringAsync()}");
                        break;
                    case RequestDataMode.raw:
                        string bodyContent = Body.Content;
                        if (browser.CanExecuteJavascriptInMainFrame)
                        {
                            bodyContent = await GetCodeStringAsync();
                        }
                        var stringContent = new StringContent(bodyContent);
                        if (contentType != null)
                        {
                            stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType.Value);
                        }
                        else
                        {
                            stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                        }
                        req.Content = stringContent;
                        AddLog($"Body请求参数：{await stringContent.ReadAsStringAsync()}");
                        break;
                    default:
                        if (contentType != null)
                            HttpClientProvider.HttpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(contentType.Value));
                        break;
                }
            }
            else
            {
                if (contentType != null)
                    HttpClientProvider.HttpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(contentType.Value));
                else
                {
                    HttpClientProvider.HttpClient.DefaultRequestHeaders.Accept.Clear();
                }
            }

            try
            {
                ReqContents.Clear();
                rep = await HttpClientProvider.HttpClient.SendAsync(req, sendCts.Token);
                IsSend = false;
                var responseString = await rep.Content.ReadAsStringAsync();
                AddLog($"请求响应内容：{responseString}");
                ReqContents.Add(new LabelModel
                {
                    Name = "响应码",
                    Text = ((int)rep.StatusCode).ToString()
                });
                AddRequestHeaders(req);
                ResponseContent = responseString;
            }
            catch (OperationCanceledException ex)
            {
                AddLog("发送请求线程终止", nameof(SendAsync));
                AddLog($"终止异常描述：{ex.Message}", nameof(SendAsync));
            }
            catch (Exception ex)
            {
                IsSend = false;
                AddLog("发送请求异常", nameof(SendAsync));
                AddLog($"发送请求异常描述：{ex.Message}", nameof(SendAsync));
                Rubyer.Message.Error($"异常错误：{ex.Message}", nameof(SendAsync));
            }
            finally
            {
                req?.Dispose();
                rep?.Dispose();
            }
        }

        private void AddRequestHeaders(HttpRequestMessage req)
        {
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.RequestUri.Host),
                Text = req.RequestUri.Host
            });
            if (req.Content == null)
                return;
            foreach (var h in req.Content.Headers)
            {
                ReqContents.Add(new LabelModel
                {
                    Name = h.Key,
                    Text = (h.Value != null ? string.Join(";", h.Value) : string.Empty)
                });
            }
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.Content.Headers.Allow),
                Text = (req.Content.Headers.Allow != null ? string.Join(";", req.Content.Headers.Allow) : string.Empty)
            });
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.Content.Headers.ContentEncoding),
                Text = (req.Content.Headers.ContentEncoding != null ? string.Join(";", req.Content.Headers.ContentEncoding) : string.Empty)
            });
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.Content.Headers.ContentLanguage),
                Text = (req.Content.Headers.ContentLanguage != null ? string.Join(";", req.Content.Headers.ContentLanguage) : string.Empty)
            });
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.Content.Headers.Expires),
                Text = (req.Content.Headers.Expires != null ? string.Join(";", req.Content.Headers.Expires) : string.Empty)
            });
            reqContents.Add(new LabelModel
            {
                Name = nameof(req.Content.Headers.ContentRange),
                Text = (req.Content.Headers.ContentRange != null ? string.Join(";", req.Content.Headers.ContentRange) : string.Empty)
            });
            ReqContents = new BindableCollection<LabelModel>(ReqContents.OrderBy(x => x.Name));
        }

        /// <summary>
        /// 取消请求
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async void CancelAsync()
        {
            if (!IsSend)
                throw new Exception("正在取消中");
            sendCts?.Cancel();
            IsSend = false;
        }

        /// <summary>
        /// Workspace变更选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void WorkspaceChanged(object sender, SelectionChangedEventArgs e)
        {
            var combobox = (ComboBox)sender;
            if (combobox == null)
                return;
            var selected = (WorkSpaceEntity)combobox.SelectedItem;

            if (SelectedWorkspace != null && selected == null)
            {
                var hasExist = Workspaces.Any(x => x.Id == SelectedWorkspace.Id);
                if (hasExist)
                    combobox.SelectedItem = SelectedWorkspace;
            }

            if (SelectedWorkspace != null)
            {
                workSpaceSerivce.UpdateSelected(SelectedWorkspace.Id);
                GetNodeTree();
            }
        }

        #region 导航操作
        /// <summary>
        /// 工作空间新增或编辑
        /// </summary>
        /// <param name="mode"></param>
        public async void ShowWorkSpaceDialog(int mode = 0)
        {
            var viewModel = GetManBootstrapper.GetService<WorkSpaceViewModel>();
            var view = ViewLocator.LocateForModel(viewModel, null, null);
            if (view is FrameworkElement fe)
            {
                fe.DataContext = viewModel;
            }

            long id = 0;
            if (mode > 0)
            {
                id = (SelectedWorkspace != null ? SelectedWorkspace.Id : 0);
            }

            var parameters = new Parameters { { DialogCommanKeys.Id, id } };
            var outParameters = await Dialog.Show(view, parameters: parameters);
            if (outParameters is Parameters outParams)
            {
                outParams.TryGetValue<bool>(DialogCommanKeys.Refresh, out bool refresh);
                outParams.TryGetValue<WorkSpaceEntity>(DialogCommanKeys.Model, out var outModel);
                if (refresh)
                {
                    if (mode > 0)
                    {
                        var currModel = Workspaces.FirstOrDefault(x => x.Id == id);
                        var index = Workspaces.IndexOf(currModel);
                        Workspaces.Remove(currModel);
                        Workspaces.Insert(index, outModel);
                        SelectedWorkspace = outModel;
                    }
                    else
                    {
                        Workspaces.Add(outModel);
                    }
                }
            }
        }

        /// <summary>
        /// 集合新增或编辑弹窗
        /// </summary>
        public async void ShowNodeDialog(NodeTypeEnum nodeType, long id = 0, long parentId = 0)
        {
            await ShowNodeDialogOperation(nodeType, id, parentId);
        }

        public async Task<NodeTreeModel> ShowNodeDialogOperation(NodeTypeEnum nodeType, long id = 0, long parentId = 0)
        {
            if (SelectedWorkspace == null || SelectedWorkspace.Id == 0)
            {
                Rubyer.Message.Warning("未选择工作空间");
                return null;
            }

            var viewModel = GetManBootstrapper.GetService<NodeViewModel>();
            var view = ViewLocator.LocateForModel(viewModel, null, null);
            if (view is FrameworkElement fe)
            {
                fe.DataContext = viewModel;
            }


            var parameters = new Parameters {
                { DialogCommanKeys.Id, id },
                { DialogCommanKeys.WorkSpaceId, SelectedWorkspace.Id },
                { DialogCommanKeys.ParentId, parentId },
                { DialogCommanKeys.NodeType, nodeType },
            };
            var outParameters = await Dialog.Show(view, parameters: parameters);
            NodeTreeModel newNode = null;
            if (outParameters is Parameters outParams)
            {
                outParams.TryGetValue<bool>(DialogCommanKeys.Refresh, out bool refresh);
                outParams.TryGetValue<NodesEntity>(DialogCommanKeys.Model, out var outModel);
                if (refresh)
                {
                    newNode = new NodeTreeModel
                    {
                        Name = outModel.NodeName,
                        Id = outModel.Id,
                        NodeType = outModel.NodeType,
                        ParentId = outModel.ParentId,
                    };
                    if (outModel.ParentId == 0)
                    {
                        if (id > 0)
                        {
                            var currModel = NodeTreeModels.FirstOrDefault(x => x.Id == id);
                            var index = NodeTreeModels.IndexOf(currModel);
                            newNode.Children = currModel?.Children;
                            NodeTreeModels.Remove(currModel);
                            NodeTreeModels.Insert(index, newNode);
                        }
                        else
                        {
                            NodeTreeModels.Add(newNode);
                        }
                    }
                    else
                    {
                        NodeTreeModel parentNode = null;


                        parentNode = FindChildNodeById(outModel.ParentId, NodeTreeModels);
                        if (parentNode == null)
                        {
                            Rubyer.Message.Error("出现异常情况,父级菜单空值");
                            return newNode;
                        }
                        if (id > 0)
                        {
                            var currModel = FindChildNodeById(id, NodeTreeModels);
                            if (currModel != null)
                                currModel.Name = outModel.NodeName;
                        }
                        else
                        {
                            if (parentNode.Children == null)
                            {
                                parentNode.Children = new BindableCollection<NodeTreeModel>();
                            }
                            parentNode.IsExpand = true;
                            parentNode.Children.Add(newNode);
                        }
                    }
                }
            }

            return newNode;
        }

        /// <summary>
        /// 查找树节点子类
        /// </summary>
        /// <param name="id"></param>
        /// <param name="lst"></param>
        /// <returns></returns>
        private NodeTreeModel FindChildNodeById(long id, BindableCollection<NodeTreeModel> lst)
        {
            if (lst == null || !lst.Any())
                return null;
            var currNode = lst.FirstOrDefault(x => x.Id == id);
            if (currNode == null)
            {
                foreach (var item in lst)
                {
                    currNode = FindChildNodeById(id, item.Children);
                    if (currNode != null)
                    {
                        return currNode;
                    }
                }
            }
            return currNode;
        }

        /// <summary>
        /// 编辑节点
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="Exception"></exception>
        public void EditTreeNode(NodeTreeModel model)
        {
            ShowNodeDialog(model.NodeType, model.Id, model.ParentId);
        }

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="Exception"></exception>
        public async void DeleteTreeNode(NodeTreeModel model)
        {
            var result = await Rubyer.MessageBoxR.Confirm("是否要进行删除，此操作不可逆!?");
            if (result != MessageBoxResult.Yes)
            {
                return;
            }
            if (model.ParentId == 0)
            {
                //直接删除
                NodeTreeModels.Remove(model);
            }
            else
            {
                //查找父节点
                var parentNode = FindChildNodeById(model.ParentId, NodeTreeModels);
                if (parentNode != null && parentNode.Children != null && parentNode.Children.Any())
                {
                    parentNode.Children.Remove(model);
                }
            }
            //执行数据库操作
            bool isDeleted = nodeService.DeleteWithChildren(model.Id);
            if (isDeleted)
                Rubyer.Message.Success("删除成功");
        }
        /// <summary>
        /// 新增子节点
        /// </summary>
        public void AddChild(NodeTreeModel model, NodeTypeEnum childType)
        {
            ShowNodeDialog(childType, 0, model.Id);
        }

        /// <summary>
        /// 新增一个新的请求
        /// </summary>
        /// <param name="node"></param>
        public async void AddRequest(NodeTreeModel node)
        {
            var newNode = await ShowNodeDialogOperation(NodeTypeEnum.Request, 0, node.Id);
            if (newNode != null && newNode.Id > 0)
            {
                var requestEntity = new RequestEntity
                {
                    RequestMethod = HttpMethod.Get.ToString().ToUpper(),
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    NodeId = newNode.Id
                };
                var requestId = requestService.AddOrUpdate(requestEntity);

                Url = string.Empty;
                SelectedMethod = "GET";

            }
        }

        private List<string> GetParentLst(NodeTreeModel node)
        {
            List<string> lst = new List<string>();
            if (NodeTreeModels == null || !NodeTreeModels.Any())
                return lst;
            var strList = FindParentById(node.ParentId, NodeTreeModels);
            return strList;
        }

        private List<string> FindParentById(long id, BindableCollection<NodeTreeModel> lst)
        {
            var strLst = new List<string>();
            if (lst == null || !lst.Any())
                return strLst;
            NodeTreeModel currNode = null;
            while ((currNode = FindChildNodeById(id, lst)) != null && id != 0)
            {
                strLst.Add(currNode.Name);
                id = currNode.ParentId;
            }
            return strLst;
        }

        /// <summary>
        /// 切换选择左侧节点
        /// </summary>
        /// <param name="nodeObj"></param>
        public async void NodeTree_SelectedItemChanged(object nodeObj)
        {
            if (!(nodeObj is NodeTreeModel node))
            {
                return;
            }

            if (node.NodeType != NodeTypeEnum.Request)
                return;

            //取消请求中操作
            sendCts?.Cancel();

            SelectedNode = node;
            //面包屑路径配置
            var strList = GetParentLst(node);
            if (strList.Any())
            {
                strList.Reverse();
                Crumbs = string.Join(" / ", strList) + " / ";
            }
            else
            {
                Crumbs = string.Empty;
            }

            //查询请求信息
            var requestEntity = requestService.GetByNodeId(node.Id);
            Url = requestEntity.RequestUrl;
            SelectedMethod = requestEntity.RequestMethod;

            //查询Url请求参数
            var newUrlParams = KeyValueConvert(requestEntity.RequestParams);
            ParamsListViewModel.ResetLst(Url, newUrlParams);

            //请求头参数
            var headers = KeyValueConvert(requestEntity.RequestHeader);
            HeaderListViewModel.ResetLst(headers);

            //formdata
            var formDatas = KeyValueConvert(requestEntity.RequestFormData);
            FormDataViewModel.ResetLst(formDatas);

            var formUrlEncodes = KeyValueConvert(requestEntity.RequestFormUrlEncodeData);
            FormUrlEncodeDataViewModel.ResetLst(formUrlEncodes);

            DataMode = requestEntity.DataMode;
            ChangeDataModeTabItem();

            //body
            Body = new RequestBodyModel()
            {
                Content = requestEntity.RequestBody,
                Mode = requestEntity.RequestMode
            };

            SelectedDataBodyMode = DataBodyModes.FirstOrDefault(x => x.Name.Equals(Body.Mode.ToString(), StringComparison.OrdinalIgnoreCase));

            await SetCodeStringAsync(Body.Content);
            CallBrowser_FuncBeatify();
        }

        private void ChangeDataModeTabItem()
        {
            Caliburn.Micro.Execute.OnUIThread(() =>
            {
                if (!(base.GetView() is Control c))
                    return;
                var tab = (TabControl)c.FindName("DataModeTab");
                if (tab == null)
                    return;
                switch (DataMode)
                {
                    case RequestDataMode.formData:
                        tab.SelectedIndex = 1;
                        break;
                    case RequestDataMode.formUrlEncode:
                        tab.SelectedIndex = 2;
                        break;
                    case RequestDataMode.raw:
                        tab.SelectedIndex = 3;
                        break;
                    case RequestDataMode.none:
                    default:
                        tab.SelectedIndex = 0;
                        break;
                }
            });
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        public async void SaveData()
        {
            if (SelectedNode == null)
                return;

            var confirmRet = await Rubyer.MessageBoxR.Confirm("您确定要保存当前请求信息!?");
            if (confirmRet != MessageBoxResult.Yes)
                return;

            var nodeId = selectedNode.Id;
            var nodeEntity = nodeService.Get(nodeId);

            var requestEntity = requestService.GetByNodeId(nodeId);
            requestEntity.RequestMethod = SelectedMethod;
            requestEntity.RequestUrl = Url;
            requestEntity.RequestParams = ConvertToKeyValue(ParamsListViewModel.ParamsList).ToJson();
            requestEntity.RequestHeader = ConvertToKeyValue(HeaderListViewModel.ParamsList).ToJson();
            requestEntity.RequestFormData = ConvertToKeyValue(FormDataViewModel.ParamsList).ToJson();
            requestEntity.RequestFormUrlEncodeData = ConvertToKeyValue(FormUrlEncodeDataViewModel.ParamsList).ToJson();
            requestEntity.DataMode = DataMode;
            requestEntity.RequestMode = (BodyTypeEnum)Enum.Parse(typeof(BodyTypeEnum), SelectedDataBodyMode.Name);

            if (browser.CanExecuteJavascriptInMainFrame)
            {
                requestEntity.RequestBody = await GetCodeStringAsync();
                CallBrowser_FuncBeatify();
                Body.Content = requestEntity.RequestBody;
            }
            else
            {
                requestEntity.RequestBody = Body.Content;
            }

            //更新请求信息
            requestService.Update(requestEntity);

        }

        private List<KeyValueModel> ConvertToKeyValue(BindableCollection<ParamsModel> lst)
        {
            var newLst = new List<KeyValueModel>();
            if (lst == null || !lst.Any())
                return newLst;
            var currLst = lst.Where(x => x.ShowCheckBox);
            foreach (var item in currLst)
            {
                newLst.Add(new KeyValueModel
                {
                    UniqueId = item.UniqueId,
                    Key = item.Key,
                    Value = item.Value,
                    Description = item.Description,
                    ShowWaterMark = item.ShowWaterMark,
                    IsChecked = item.IsChecked,
                    ShowBtnDel = item.ShowBtnDel,
                    ShowCheckBox = item.ShowCheckBox
                });
            }
            return newLst;
        }
        private List<ParamsModel> KeyValueConvert(string jsonString)
        {
            var newLst = new List<ParamsModel>();
            var currLst = jsonString.ToObject<List<KeyValueModel>>();
            if (currLst == null || !currLst.Any())
                return newLst;
            foreach (var item in currLst)
            {
                newLst.Add(new ParamsModel
                {
                    UniqueId = item.UniqueId,
                    Key = item.Key,
                    Value = item.Value,
                    Description = item.Description,
                    ShowWaterMark = item.ShowWaterMark,
                    IsChecked = item.IsChecked,
                    ShowBtnDel = item.ShowBtnDel,
                    ShowCheckBox = item.ShowCheckBox
                });
            }
            return newLst;
        }

        /// <summary>
        /// 选中节点名称变更
        /// </summary>
        //public void SelectedNodeNameChanged(object sender, TextChangedEventArgs e)
        //{
        //    if (selectedNode == null)
        //        return;
        //    var node = nodeService.Get(selectedNode.Id);
        //    if (node != null)
        //    {
        //        node.NodeName = selectedNode.Name;
        //        nodeService.Update(node);
        //    }
        //}
        #endregion

        #endregion


        /// <summary>
        /// 查询工作空间列表
        /// </summary>
        public void GetWorkSpaces()
        {
            var workspaceLst = workSpaceSerivce.GetAll();
            Workspaces = new BindableCollection<WorkSpaceEntity>(workspaceLst);
            SelectedWorkspace = workspaceLst.FirstOrDefault(x => x.IsSelected);
            if (SelectedWorkspace == null)
            {
                SelectedWorkspace = workspaceLst.FirstOrDefault();
            }
            GetNodeTree();
        }

        public void GetNodeTree()
        {
            if (SelectedWorkspace == null)
            {
                NodeTreeModels.Clear();
                return;
            }
            //填充导航数据
            NodeTreeModels = new BindableCollection<NodeTreeModel>();
            var nodes = nodeService
                .GetByWorkspaceId(SelectedWorkspace.Id)
                .Select(x => new NodeTreeModel
                {
                    Name = x.NodeName,
                    Id = x.Id,
                    ParentId = x.ParentId,
                    NodeType = x.NodeType
                }).ToList();
            if (!nodes.Any())
                return;
            NodeTreeModels = new BindableCollection<NodeTreeModel>(nodes.Where(x => x.ParentId == 0));
            CreateNodeTree(new BindableCollection<NodeTreeModel>(nodes), NodeTreeModels);
        }

        private void CreateNodeTree(BindableCollection<NodeTreeModel> all, BindableCollection<NodeTreeModel> currLst)
        {
            foreach (var p in currLst)
            {
                p.Children = new BindableCollection<NodeTreeModel>(all.Where(x => x.ParentId == p.Id));
                CreateNodeTree(all, p.Children);
            }
        }
    }
}